<?php

namespace app\api\controller;

use Throwable;
use ba\PayLib;
use think\facade\Log;
use Yansongda\Pay\Pay;
use app\common\controller\Frontend;
use app\common\model\enneagram\Results;
use app\common\model\Order;
use app\common\model\Payment;
use Psr\Http\Message\ResponseInterface;
use think\facade\Db;

class PayNotify extends Frontend
{
    protected array $noNeedLogin = ['wechat', 'alipay'];
    // 无需鉴权的方法
    protected array $noNeedPermission = ['*'];
    /**
     * @throws Throwable
     */
    public function initialize(): void
    {
        parent::initialize();
    }
    // {
    //     "transaction_id":"1217752501201407033233368018",
    //     "amount":{
    //         "payer_total":100,
    //         "total":100,
    //         "currency":"CNY",
    //         "payer_currency":"CNY"
    //     },
    //     "mchid":"1230000109",
    //     "trade_state":"SUCCESS",
    //     "bank_type":"CMC",
    //     "promotion_detail":[
    //         {
    //             "amount":100,
    //             "wechatpay_contribute":0,
    //             "coupon_id":"109519",
    //             "scope":"GLOBAL",
    //             "merchant_contribute":0,
    //             "name":"单品惠-6",
    //             "other_contribute":0,
    //             "currency":"CNY",
    //             "stock_id":"931386",
    //             "goods_detail":[
    //                 {
    //                     "goods_remark":"商品备注信息",
    //                     "quantity":1,
    //                     "discount_amount":1,
    //                     "goods_id":"M1006",
    //                     "unit_price":100
    //                 },
    //                 {
    //                     "goods_remark":"商品备注信息",
    //                     "quantity":1,
    //                     "discount_amount":1,
    //                     "goods_id":"M1006",
    //                     "unit_price":100
    //                 }
    //             ]
    //         },
    //         {
    //             "amount":100,
    //             "wechatpay_contribute":0,
    //             "coupon_id":"109519",
    //             "scope":"GLOBAL",
    //             "merchant_contribute":0,
    //             "name":"单品惠-6",
    //             "other_contribute":0,
    //             "currency":"CNY",
    //             "stock_id":"931386",
    //             "goods_detail":[
    //                 {
    //                     "goods_remark":"商品备注信息",
    //                     "quantity":1,
    //                     "discount_amount":1,
    //                     "goods_id":"M1006",
    //                     "unit_price":100
    //                 },
    //                 {
    //                     "goods_remark":"商品备注信息",
    //                     "quantity":1,
    //                     "discount_amount":1,
    //                     "goods_id":"M1006",
    //                     "unit_price":100
    //                 }
    //             ]
    //         }
    //     ],
    //     "success_time":"2018-06-08T10:34:56+08:00",
    //     "payer":{
    //         "openid":"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"
    //     },
    //     "out_trade_no":"1217752501201407033233368018",
    //     "appid":"wxd678efh567hg6787",
    //     "trade_state_desc":"支付成功",
    //     "trade_type":"APP",
    //     "attach":"自定义数据",
    //     "scene_info":{
    //         "device_id":"013467007045764"
    //     }
    // }

    /**
     * 微信支付回调
     * @throws Throwable
     */
    public function wechat(): ResponseInterface
    {
        Pay::config(PayLib::getConfig());
        $result = Pay::wechat()->callback();
        Log::write('收到回调数据Wechat：' . json_encode($result));

        // 验证支付状态
        if ($result['return_code'] !== 'SUCCESS' || $result['result_code'] !== 'SUCCESS') {
            Log::write('支付失败：' . ($result['return_msg'] ?? '未知错误'));
            return Pay::wechat()->success();
        }

        // 获取商户订单号
        $outTradeNo = $result['out_trade_no'];

        // 查询订单信息
        $order = Order::where('order_no', $outTradeNo)->find();
        if (!$order) {
            Log::write('订单不存在：' . $outTradeNo);
            return Pay::wechat()->success();
        }

        // 验证订单金额（微信返回单位为分，需要转换为元）
        $totalFee = $result['total_fee'] / 100;
        if (bccomp($totalFee, $order->amount, 2) !== 0) {
            Log::write('订单金额不匹配：微信支付金额' . $totalFee . '元，订单金额' . $order->amount . '元');
            return Pay::wechat()->success();
        }

        // 检查订单是否已处理（幂等性处理）
        if ($order->pay_status === '1') {
            Log::write('订单已处理，无需重复处理：' . $outTradeNo);
            return Pay::wechat()->success();
        }

        // 开启事务
        Db::startTrans();
        try {
            // 更新订单状态
            $order->save([
                'pay_status' => Order::PAY_STATUS_PAID, // 已支付
                'paid_at' => date('Y-m-d H:i:s', time()),
                'update_time' => time(),
                'payment_method' => 'wechat',
            ]);

            // 如果存在关联的报告，更新报告支付状态
            if ($order->result_id > 0) {
                Results::update([
                    'pay_status' => Results::PAY_STATUS_PAID, // 已支付
                    'update_time' => time()
                ], ['id' => $order->result_id]);
            }

            // 记录支付流水
            Payment::create([
                'order_id' => $order->id,
                'payment_method' => 'wechat',
                'amount' => $totalFee,
                'transaction_id' => $result['transaction_id'] ?? '',
                'payment_data' => json_encode($result, JSON_UNESCAPED_UNICODE),
                'pay_status' => Payment::PAY_STATUS_PAID, // 支付成功
                'create_time' => time(),
                'update_time' => time(),
                'remark' => '微信支付回调自动处理'
            ]);

            Db::commit();
        } catch (Throwable $e) {
            Db::rollback();
            Log::write('订单处理异常：' . $e->getMessage());
        }
        // 无论处理成功与否，都返回成功响应给微信服务器，避免重复通知
        return Pay::wechat()->success();
    }

    // CREATE TABLE `payment` (
    //     `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
    //     `order_id` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '订单ID',
    //     `payment_method` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '支付方式，alipay,wechat等' COLLATE 'utf8mb4_unicode_ci',
    //     `amount` DECIMAL(10,2) NOT NULL DEFAULT '0.00' COMMENT '支付金额',
    //     `transaction_id` VARCHAR(255) NULL DEFAULT '' COMMENT '第三方交易号' COLLATE 'utf8mb4_unicode_ci',
    //     `payment_data` JSON NULL DEFAULT NULL COMMENT '支付原始数据',
    //     `pay_status` ENUM('0','1','2') NULL DEFAULT '0' COMMENT '下拉框:0=未支付,1=支付成功,2=支付失败' COLLATE 'utf8mb4_unicode_ci',
    //     `create_time` BIGINT(16) UNSIGNED NULL DEFAULT NULL COMMENT '创建时间',
    //     `update_time` BIGINT(16) UNSIGNED NULL DEFAULT NULL COMMENT '修改时间',
    //     `remark` TEXT NULL DEFAULT NULL COMMENT '备注' COLLATE 'utf8mb4_unicode_ci',
    //     PRIMARY KEY (`id`) USING BTREE,
    //     UNIQUE INDEX `payment_no` (`payment_no`) USING BTREE,
    //     INDEX `order_id` (`order_id`) USING BTREE
    // )
    // CREATE TABLE `order` (
    //     `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
    //     `status` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' COMMENT '状态:0=禁用,1=启用',
    //     `order_no` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '订单编号' COLLATE 'utf8mb4_unicode_ci',
    //     `user_id` INT(10) UNSIGNED NULL DEFAULT '0' COMMENT '用户id',
    //     `result_id` INT(10) UNSIGNED NULL DEFAULT '0' COMMENT '报告id',
    //     `amount` DECIMAL(10,2) NULL DEFAULT '0.00' COMMENT '订单金额',
    //     `pay_status` ENUM('0','1','2') NULL DEFAULT '0' COMMENT '下拉框:0=未支付,1=已支付,2=已取消' COLLATE 'utf8mb4_unicode_ci',
    //     `paid_at` DATETIME NULL DEFAULT NULL COMMENT '支付时间',
    //     `create_time` BIGINT(16) UNSIGNED NULL DEFAULT NULL COMMENT '创建时间',
    //     `update_time` BIGINT(16) UNSIGNED NULL DEFAULT NULL COMMENT '修改时间',
    //     `remark` TEXT NULL DEFAULT NULL COMMENT '备注' COLLATE 'utf8mb4_unicode_ci',
    //     PRIMARY KEY (`id`) USING BTREE,
    //     UNIQUE INDEX `order_no` (`order_no`) USING BTREE,
    //     INDEX `result_id` (`result_id`) USING BTREE
    // )
    // CREATE TABLE `results` (
    //     `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
    //     `user_id` INT(10) UNSIGNED NULL DEFAULT NULL COMMENT '用户id',
    //     `order_id` INT(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '关联订单ID',
    //     `raw_scores` JSON NOT NULL COMMENT '原始得分',
    //     `scores` JSON NOT NULL COMMENT '存储归一化后的得分',
    //     `selected_options` JSON NOT NULL COMMENT '存储用户每道题的选择项',
    //     `selected_types` JSON NOT NULL COMMENT '存储用户每道题选择的类型',
    //     `report_data` JSON NOT NULL COMMENT '报告数据JSON',
    //     `main_type` TINYINT(4) UNSIGNED NOT NULL COMMENT '主要类型',
    //     `wing_type` TINYINT(4) UNSIGNED NOT NULL COMMENT '翼型',
    //     `pay_status` ENUM('0','1') NOT NULL DEFAULT '0' COMMENT '下拉框:0=未支付,1=已支付' COLLATE 'utf8mb4_unicode_ci',
    //     `create_time` BIGINT(16) UNSIGNED NULL DEFAULT NULL COMMENT '创建时间',
    //     `update_time` BIGINT(16) UNSIGNED NULL DEFAULT NULL COMMENT '修改时间',
    //     `status` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' COMMENT '状态:0=禁用,1=启用',
    //     `isFinish` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0' COMMENT '是否完成：0=进行中，1=已完成',
    //     PRIMARY KEY (`id`) USING BTREE
    // )
    // 
    /**
     * 支付宝支付回调
     * @throws Throwable
     */
    public function alipay(): ResponseInterface
    {
        try {
            Pay::config(PayLib::getConfig());
            $result = Pay::alipay()->callback();
            // $result = [
            //     'notify_time' => '通知时间', // 格式：yyyy-MM-dd HH:mm:ss
            //     'notify_type' => '通知类型', // trade_status_sync
            //     'notify_id' => '通知校验ID', // 支付宝唯一通知ID
            //     'app_id' => '支付宝应用ID', // 如：2014072300007148
            //     'charset' => '编码格式', // 如：UTF-8
            //     'version' => '接口版本', // 如：1.0
            //     'sign_type' => '签名类型', // RSA2
            //     'sign' => '签名值',
            //     'trade_no' => '支付宝交易号', // 支付宝唯一交易号
            //     'out_trade_no' => '商户订单号', // 对应你系统的订单号
            //     'out_biz_no' => '商户业务号',
            //     'buyer_id' => '买家支付宝用户ID',
            //     'buyer_logon_id' => '买家支付宝账号',
            //     'seller_id' => '卖家支付宝用户ID',
            //     'seller_email' => '卖家支付宝账号',
            //     'trade_status' => '交易状态', // 如：TRADE_SUCCESS
            //     'total_amount' => '订单金额', // 单位：元
            //     'receipt_amount' => '实收金额', // 单位：元
            //     'invoice_amount' => '开票金额', // 单位：元
            //     'buyer_pay_amount' => '付款金额', // 单位：元
            //     'point_amount' => '积分金额', // 单位：元
            //     'refund_fee' => '退款金额', // 单位：元
            //     'subject' => '订单标题',
            //     'body' => '商品描述',
            //     'gmt_create' => '交易创建时间', // 格式：yyyy-MM-dd HH:mm:ss
            //     'gmt_payment' => '交易付款时间', // 格式：yyyy-MM-dd HH:mm:ss
            //     'gmt_refund' => '交易退款时间', // 格式：yyyy-MM-dd HH:mm:ss
            //     'gmt_close' => '交易结束时间', // 格式：yyyy-MM-dd HH:mm:ss
            //     'fund_bill_list' => '支付金额信息', // JSON字符串
            //     'passback_params' => '回传参数', // 商户自定义参数
            //     'voucher_detail_list' => '优惠券信息' // JSON字符串
            // ];
            ### 关键字段说明
            // 1. out_trade_no - 你系统生成的订单号（最重要字段）
            // 2. trade_no - 支付宝交易号（支付宝系统唯一标识）
            // 3. total_amount - 订单金额（单位元，字符串格式）
            // 4. trade_status - 交易状态（TRADE_SUCCESS表示支付成功）
            // 5. buyer_id - 买家支付宝用户ID
            // 6. gmt_payment - 支付时间（可用于记录支付完成时间）
            // ### 交易状态(trade_status)可能值
            // - WAIT_BUYER_PAY ：交易创建，等待买家付款
            // - TRADE_CLOSED ：未付款交易超时关闭，或支付完成后全额退款
            // - TRADE_SUCCESS ：交易支付成功
            // - TRADE_FINISHED ：交易结束，不可退款
            // ### 注意事项
            // 1. 必须验证签名 ：使用支付宝公钥验证sign字段确保回调真实性
            // 2. 金额验证 ：比较total_amount与系统订单金额是否一致
            // 3. 幂等处理 ：相同trade_no可能多次通知，需做防重复处理
            // 4. 日志记录 ：建议记录所有回调字段用于排查问题
            // 5. 异步处理 ：处理成功后必须返回success给支付宝，否则支付宝会重试
            // 建议在实际业务处理中添加这些验证逻辑，确保支付回调的安全性和准确性。
            Log::write('收到回调数据：' . json_encode($result));
        } catch (Throwable $e) {
            Log::write('支付回调异常' . $e->getMessage());
        }

        return Pay::alipay()->success();
    }
}
